package td.pt.widget;

import td.client.ClientState;
import td.client.ui.Button;
import td.domain.Category;
import td.domain.DemoStore;
import td.domain.util.StatisticalComparison;
import td.pt.event.CreateTopicEvent;
import td.pt.event.EditEvent;
import td.pt.event.EditEvent.EditHandler;
import td.pt.event.UseCategoryNavigationEvent;
import td.pt.event.UseCategoryNavigationEvent.UseCategoryNavigationHandler;
import td.pt.event.UseTopicNavigationEvent;
import td.pt.widget.TopicListingPopupPresenter.TopicNavigationType;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.cellview.client.CellBrowser;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.view.client.SingleSelectionModel;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;
import com.gwtplatform.mvp.client.PopupView;
import com.gwtplatform.mvp.client.PresenterWidget;
import com.gwtplatform.mvp.client.proxy.RevealRootPopupContentEvent;

public class CategoryTreePopupPresenter extends
		PresenterWidget<CategoryTreePopupPresenter.MyView> {

	public enum CategoryNavigationType {
		SELECT_THOUGHTS_IN_CATEGORY, ADD_THOUGHT_TO_CATEGORY;
	}

	public interface MyView extends PopupView {
		Button getSelectCategory();

		Button getAddToExistingTopic();

		Button getAddToNewTopic();

		Button getCancel();

		CellBrowser getCategoryBrowser();

		SingleSelectionModel<Category> getSelectionModel();

		Label getBrowserPurposeDescription();

		public RadioButton getOrderAlphabetic();

		public RadioButton getOrderNumberOfThoughts();

		public RadioButton getOrderNumberOfReads();

		public void refresh();
	}

	UseCategoryNavigationHandler useCategoryNavigationHandler = new UseCategoryNavigationHandler() {

		@Override
		public void onUseCategoryNavigation(UseCategoryNavigationEvent event) {
			String subHeaderText = "";
			switch (event.getNavigationType()) {
			case ADD_THOUGHT_TO_CATEGORY:
				subHeaderText = "Select a Category under which your Thought will be listed.";
				getView().getAddToExistingTopic().setVisible(true);
				getView().getAddToNewTopic().setVisible(true);
				getView().getSelectCategory().setVisible(false);
				break;
			case SELECT_THOUGHTS_IN_CATEGORY:
				subHeaderText = "Select a Category to display Thoughts that are listed under it.";
				getView().getAddToExistingTopic().setVisible(false);
				getView().getAddToNewTopic().setVisible(false);
				getView().getSelectCategory().setVisible(true);
				break;
			}
			getView().getBrowserPurposeDescription().setText(subHeaderText);
			RevealRootPopupContentEvent.fire(event.getSource(),
					CategoryTreePopupPresenter.this);
		}
	};
	EditHandler editHandler = new EditHandler() {

		@Override
		public void onEdit(EditEvent event) {
			getView().hide();
		}
	};

	@Inject
	ClientState state;

	@Inject
	PresenterWidgetFactory factory;

	@Inject
	public CategoryTreePopupPresenter(final EventBus eventBus, final MyView view) {
		super(eventBus, view);
	}

	@Override
	protected void onBind() {
		super.onBind();
		registerHandler(getEventBus().addHandler(
				UseCategoryNavigationEvent.TYPE, useCategoryNavigationHandler));
		registerHandler(getEventBus().addHandler(EditEvent.TYPE, editHandler));
		getView().getSelectCategory().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				final Category category = getView().getSelectionModel()
						.getSelectedObject();
				if (category == null) {
					return;
				}
				factory.getTopicListingPresenter(new AsyncCallback<TopicListingPopupPresenter>() {

					@Override
					public void onSuccess(TopicListingPopupPresenter result) {
						UseTopicNavigationEvent useTopicNavigationEvent = new UseTopicNavigationEvent(
								TopicNavigationType.SELECT_THOUGHTS_IN_TOPIC,
								CategoryTreePopupPresenter.this, category);
						getEventBus().fireEvent(useTopicNavigationEvent);
						getView().hide();
					}

					@Override
					public void onFailure(Throwable caught) {
						Window.alert("Error displaying Topic Listings:\n"
								+ caught.getMessage());
					}
				});

			}
		});
		getView().getAddToExistingTopic().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				Category category = getView().getSelectionModel()
						.getSelectedObject();
				if (category == null) {
					return;
				}
				UseTopicNavigationEvent useTopicNavigationEvent = new UseTopicNavigationEvent(
						TopicNavigationType.ADD_THOUGHT_TO_TOPIC,
						CategoryTreePopupPresenter.this, category);
				getEventBus().fireEvent(useTopicNavigationEvent);
				getView().hide();
			}
		});
		getView().getAddToNewTopic().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				Category category = getView().getSelectionModel()
						.getSelectedObject();
				if (category == null) {
					return;
				}
				CreateTopicEvent createTopicEvent = new CreateTopicEvent(
						CategoryTreePopupPresenter.this, category);
				getEventBus().fireEvent(createTopicEvent);
				getView().hide();
			}
		});
		getView().getCancel().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				getView().hide();
			}
		});

		getView().getOrderAlphabetic().addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				refresh(StatisticalComparison.ALPHABETIC);
			}
		});
		getView().getOrderNumberOfReads().addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				refresh(StatisticalComparison.NUMBER_OF_THOUGHT_READS);
			}
		});
		getView().getOrderNumberOfThoughts().addClickHandler(
				new ClickHandler() {
					@Override
					public void onClick(ClickEvent event) {
						refresh(StatisticalComparison.NUMBER_OF_THOUGHTS);
					}
				});
	}

	private void refresh(StatisticalComparison comparisonType) {
		Category.currentComparisonType = comparisonType;
		DemoStore.db().reorder(DemoStore.db().rootCategory);
		getView().refresh();
	}

	@Override
	protected void onReveal() {
		super.onReveal();

		switch (Category.currentComparisonType) {
		case ALPHABETIC:
			getView().getOrderAlphabetic().setValue(true);
			break;
		case NUMBER_OF_THOUGHT_READS:
			getView().getOrderNumberOfReads().setValue(true);
			break;
		case NUMBER_OF_THOUGHTS:
			getView().getOrderNumberOfThoughts().setValue(true);
			break;
		default:
			Category.currentComparisonType = StatisticalComparison.NUMBER_OF_THOUGHT_READS;
			getView().getOrderNumberOfReads().setValue(true);
			break;
		}
	}
}
